package com.qdlc.p2p.biz.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.borrowworker.BorrowHelper;
import com.qdlc.p2p.biz.borrowworker.worker.BorrowWorker;
import com.qdlc.p2p.biz.executer.AbstractExecuter;
import com.qdlc.p2p.biz.executer.ExecuterHelper;
import com.qdlc.p2p.biz.executer.impl.BorrowCompensateSuccessExecuter;
import com.qdlc.p2p.biz.executer.impl.BorrowRepayFreezeExecuter;
import com.qdlc.p2p.biz.executer.impl.BorrowRepaySuccessExecuter;
import com.qdlc.p2p.biz.executer.impl.CancelTenderUnFeezeExcuter;
import com.qdlc.p2p.biz.executer.impl.ExperienceCancelTenderExecuter;
import com.qdlc.p2p.biz.executer.impl.ExperienceExecuter;
import com.qdlc.p2p.biz.executer.impl.RedEnvelopeBorrowTenderFailExecuter;
import com.qdlc.p2p.biz.executer.impl.UserRedEnvelopeExecuter;
import com.qdlc.p2p.biz.service.AutoBorrowService;
import com.qdlc.p2p.biz.service.TppInvestService;
import com.qdlc.p2p.biz.service.borrow.BorrowFullVerifyService;
import com.qdlc.p2p.biz.task.ConcurrentUtil;
import com.qdlc.p2p.common.constant.BondStatus;
import com.qdlc.p2p.common.constant.BorrowAutoType;
import com.qdlc.p2p.common.constant.BorrowRepaymentStatus;
import com.qdlc.p2p.common.constant.BorrowRepaymentType;
import com.qdlc.p2p.common.constant.BorrowStatus;
import com.qdlc.p2p.common.constant.BorrowTenderStatus;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.exception.BorrowException;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.checkrule.AutoTenderConfRuleCheck;
import com.qdlc.p2p.dal.common.RuleCheckHelper;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter.Operators;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dao.BondDao;
import com.qdlc.p2p.dal.dao.BorrowAutoDao;
import com.qdlc.p2p.dal.dao.BorrowCollectionDao;
import com.qdlc.p2p.dal.dao.BorrowDao;
import com.qdlc.p2p.dal.dao.BorrowRepaymentDao;
import com.qdlc.p2p.dal.dao.BorrowTenderDao;
import com.qdlc.p2p.dal.dao.UserAutoTenderLogDao;
import com.qdlc.p2p.dal.dao.UserDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.BorrowAuto;
import com.qdlc.p2p.dal.dto.BorrowCollection;
import com.qdlc.p2p.dal.dto.BorrowRepayment;
import com.qdlc.p2p.dal.dto.BorrowTender;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserAutoTenderLog;
import com.qdlc.p2p.dal.dto.UserCache;
import com.qdlc.p2p.dal.model.BorrowModel;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.model.UserAutoTenderLogModel;
import com.qdlc.p2p.dal.util.SystemConfigs;
import com.qdlc.p2p.dal.util.UserUtils;

@Service("autoBorrowService")
public class AutoBorrowServiceImpl implements AutoBorrowService {

    private static final Logger logger = Logger.getLogger(AutoBorrowServiceImpl.class);

    @Resource
    private BorrowRepaymentDao borrowRepaymentDao;

    @Resource
    private BorrowDao borrowDao;

    @Resource
    private BorrowAutoDao borrowAutoDao;

    @Resource
    private BorrowTenderDao tenderDao;

    @Resource
    private AccountDao accountDao;

    @Resource
    private UserDao userDao;

    @Resource
    private BorrowCollectionDao borrowCollectionDao;

    @Resource
    private BondDao bondDao;

    @Resource
    private TppInvestService tppInvestService;

    @Resource
    private UserAutoTenderLogDao userAutoTenderLogDao;

    @Resource
    private BorrowFullVerifyService borrowFullVerifyService;

    @Override
    public void autoBorrowRepay(BorrowRepayment borrowRepayment) {
        logger.info("repayment_id=" + borrowRepayment.getId() + "进行还款....");
        Borrow borrow = borrowDao.find(borrowRepayment.getBorrow().getId());
        BorrowWorker worker = BorrowHelper.getWorker(borrow);
        try {
            borrowRepayment = checkRepay(borrowRepayment);
            // 处理借款人资金
            borrowRepayment.setRepaymentYesTime(DateUtil.getNow());
            worker.borrowRepayHandleBorrow(borrowRepayment);

            // 处理投资人资金
            worker.borrowRepayHandleTender(borrowRepayment);
            // 设置状态
            borrowRepayment.setStatus(BorrowRepaymentStatus.STATUS_YES_REPAY);
            // 还款类型1：正常还款
            borrowRepayment.setType(BorrowRepaymentType.REPAYMENT_TYPE_NORAML);
            // 实际还款者
            borrowRepayment.setRealRepayer(borrow.getUser());
            borrowRepayment = this.getResealRepay(borrowRepayment);// 还款信息根据情况重新封装
            borrowRepaymentDao.updateBorrowRepaymentByStatus(borrowRepayment);
            int status = worker.isLastPeriod(borrowRepayment.getPeriod()) ? 8 : 7;
            borrow.setStatus(status);

            double total = BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()); // 还款本金+利息
            borrow.setRepaymentYesAccount(BigDecimalUtil.add(borrow.getRepaymentYesAccount(), total));
            borrow.setRepaymentYesInterest(BigDecimalUtil.add(borrow.getRepaymentYesInterest(), borrowRepayment.getInterest()));
            borrowDao.update(borrow);

            // 向借款人发送还款成功通知
            Global.setTransfer("repay", borrowRepayment);
            Global.setTransfer("user", borrow.getUser());
            AbstractExecuter successExecuter = ExecuterHelper.getExecuter(BorrowRepaySuccessExecuter.class);
            successExecuter.execute(0, borrow.getUser());

            // 还款后停止相关债权转让
            bondDao.stopBond(borrow.getId(), BondStatus.STATUS_STOP_AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            // 解冻用户资金
            repayFail(borrowRepayment);
            logger.error("还款失败");
            throw new BorrowException("还款失败" + e.getMessage());
        }
    }

    private void repayFail(BorrowRepayment borrowRepayment) {
        borrowRepayment.setWebStatus(0);
        borrowRepaymentDao.update(borrowRepayment);
    }

    @Override
    public void webAdvance(BorrowRepayment borrowRepayment) {
        borrowRepayment = borrowRepaymentDao.find(borrowRepayment.getId());
        Borrow borrow = borrowRepayment.getBorrow();
        BorrowWorker worker = BorrowHelper.getWorker(borrow);
        try {
            // 还款列表
            List<BorrowCollection> list = borrowCollectionDao.list(borrow.getId(), borrowRepayment.getPeriod());

            // 处理投资人资金
            worker.borrowRepayHandleTender(borrowRepayment);
            // 网站垫付
            borrowRepayment.setStatus(BorrowRepaymentStatus.STATUS_INSTEAD_REPAY);
            borrowRepayment.setRepaymentYesTime(DateUtil.getNow());
            borrowRepayment.setRepaymentYesAccount(BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()));
            if (borrowRepayment.getRealRepayer() == null) {// 如果是标准版，并且等于空，则默认为是平台垫付
                borrowRepayment.setRealRepayer(new User(SystemConfigs.ADMIN_ID));
            }
            borrowRepaymentDao.updateBorrowRepaymentByStatus(borrowRepayment);
            double total = BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()); // 还款表本金+利息
            borrow.setRepaymentYesAccount(BigDecimalUtil.add(borrow.getRepaymentYesAccount(), total));
            borrow.setRepaymentYesInterest(borrow.getRepaymentYesInterest() + borrowRepayment.getInterest());
            borrowDao.update(borrow);

            // 第三方业务
            tppInvestService.doTppWebAdvance(list);

        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void overduePayment(BorrowRepayment borrowRepayment) {
        Borrow borrow = borrowDao.find(borrowRepayment.getBorrow().getId());
        BorrowWorker worker = BorrowHelper.getWorker(borrow);
        try {
            // 处理借款人资金
            worker.borrowRepayHandleBorrow(borrowRepayment);

            // 处理逾期垫付的状态才2更新到1
            // 已还款
            borrowRepayment.setStatus(BorrowRepaymentStatus.STATUS_REPAY_ING);
            borrowRepaymentDao.updateBorrowRepaymentStatus(borrowRepayment);

            int status = worker.isLastPeriod(borrowRepayment.getPeriod()) ? 8 : 7;
            borrow.setStatus(status);
            double total = BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()); // 还款表本金+利息
            borrow.setRepaymentYesAccount(BigDecimalUtil.add(borrow.getRepaymentYesAccount(), total));
            borrow.setRepaymentYesInterest(borrow.getRepaymentYesInterest() + borrowRepayment.getInterest());
            borrowDao.update(borrow);

            // 处理第三方业务
            tppInvestService.doTppLateRepayment(borrowRepayment);

        } catch (Exception e) {
            logger.error("还款失败");
            throw new BorrowException("还款失败");
        }

    }

    @Override
    public void doPriorRepay(BorrowRepayment borrowRepayment) {
        if (borrowRepayment.getStatus() != BorrowRepaymentStatus.STATUS_YES_REPAY) {
            throw new BorrowException("请勿重复还款", BusinessException.TYPE_JSON);
        }
        Borrow borrow = borrowDao.find(borrowRepayment.getBorrow().getId());
        BorrowWorker worker = BorrowHelper.getWorker(borrow);
        String resultCode = null;
        double waitRemainderRepayCapital = borrowRepaymentDao.getRemainderCapital(borrow.getId()); // 计算剩余待还本金
        double waitRemainderRepayInterest = borrowRepaymentDao.getwaitRpayInterest(borrow.getId(), borrowRepayment.getPeriod()); // 本次提前还款待还利息总和
        double money = BigDecimalUtil.add(waitRemainderRepayCapital, waitRemainderRepayInterest);
        if ("EXECUTE_SUCCESS".equals(resultCode)) {
            try {
                // 处理借款人资金（提前还款）
                worker.borrowPriorRepayHandleBorrow(borrowRepayment);
                // 处理投资人资金（提前还款）
                worker.borrowPriorRepayHandleTender(borrowRepayment);
                borrowRepayment.setStatus(BorrowRepaymentStatus.STATUS_YES_REPAY);
                borrowRepayment.setRepaymentYesTime(DateUtil.getNow());
                borrowRepayment.setRepaymentYesAccount(BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()));
                borrowRepaymentDao.updateBorrowRepaymentStatusAndWebStatus(borrowRepayment);
                // 提前还款完成状态变成8
                borrow.setStatus(8);
                double total = BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()); // 还款本金+利息

                borrow.setRepaymentYesAccount(BigDecimalUtil.add(borrow.getRepaymentYesAccount(), total));
                borrow.setRepaymentYesInterest(borrow.getRepaymentYesInterest() + borrowRepayment.getInterest());

                borrowDao.update(borrow);
            } catch (Exception e) {
                throw new BorrowException("提前还款失败" + e.getMessage());
            }
        } else {
            Global.setTransfer("tenderAccount", money);
            Global.setTransfer("borrow", borrow);
            Global.setTransfer("repay", borrowRepayment);
            AbstractExecuter executer = ExecuterHelper.getExecuter(BorrowRepayFreezeExecuter.class);
            executer.execute(money, borrow.getUser());
        }

    }

    /**
     * 自动投标功能
     */
    @Override
    public void autoDealTender(BorrowModel model) throws Exception {
        Borrow borrow = model.prototype();
        logger.info("标ID：" + borrow.getId() + "进入自动投标流程， status:" + borrow.getStatus());
        try {
            if (borrow.getCategory().intValue() == 1) {
                if (borrow.getPutStartTime() == null || (borrow.getPutStartTime().getTime() <= DateUtil.getNow().getTime())) {
                    QueryParam param = QueryParam.getInstance();
                    param.addParam("enable", true);
                    param.addParam("user.userId", Operators.NOTEQ, model.getUserId());
                /*	// 判断系统是否开启vip等级越高自动投标优先也越高
					if (SystemConfigHelper.getIntegerValue(Nid.VIP_PRIORITY) == 1) {
						// 根据VIP等级排序
						param.addOrder(OrderType.DESC, "user.userVip.userVipLevel");
					} */
                    // 根据更新时间正序排序，投标成功后则更新为当前时间
                    param.addOrder("updateTime");
                    param.addOrder("addTime");
                    List<BorrowAuto> autoList = borrowAutoDao.findByCriteria(param);
                    if (autoList != null && autoList.size() > 0) {
                        autoTenderHelper(autoList, borrow);
                    }
                    // 自动投标结束，还原标状态
                }
            }
            borrowDao.updateStatus(borrow.getId(), 1, 19);
        } catch (Exception e) {
            // 出异常则将标重新状态置为0
            borrowDao.updateStatus(borrow.getId(), 0, 19);
            logger.error(e.getMessage());
        }
    }


    /**
     * 自动投标 判断
     *
     * @param autoList
     * @param borrow
     * @throws Exception
     */
    public void autoTenderHelper(List<BorrowAuto> autoList, Borrow borrow) throws Exception {
        AutoTenderConfRuleCheck autoTenderConf = RuleCheckHelper.getValue(AutoTenderConfRuleCheck.class);
        // 最大投标比率
        double autoTenderMaxApr = autoTenderConf.auto_tender_max_apr;
        // 最大投标金额
        double autoTenderMaxAcount = BigDecimalUtil.mul(borrow.getAccount(), autoTenderMaxApr);
        // 已经投标额度
        double totalAccountYes = borrow.getAccountYes();
        // 剩余可投
        double lastAccount = autoTenderMaxAcount;
        //用于判断是否是最后一次循环
        int num = 0;
        //最后一笔标记
        String resultFlag = "";
        List<UserAutoTenderLog> autoTenderLogList = new ArrayList<UserAutoTenderLog>();

        for (BorrowAuto borrowAuto : autoList) {
            num++;
            // 投资者
            User user = userDao.find(borrowAuto.getUser().getUserId());
            UserCache userCache = UserUtils.getUserCacheByUserId(user.getUserId());
            UserAutoTenderLog userAutoTenderLog = new UserAutoTenderLog();
            userAutoTenderLog.setUser(user);
            userAutoTenderLog.setBorrow(borrow);
            userAutoTenderLog.setAddTime(DateUtil.getNow());
            lastAccount = BigDecimalUtil.sub(autoTenderMaxAcount, totalAccountYes);
            if (lastAccount <= 0) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001010"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }

            // 用户是否被锁定是否是投资者身份校验
            if (userCache.getStatus() == 1 || userCache.getUserType() == 2 || userCache.getUserType() == 3) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001001"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }
            // 自动投标还款方式校验
            if (StringUtil.isNotBlank(borrowAuto.getStyle())) {
                if (!borrowAuto.getStyle().contains(borrow.getStyle() + "")) {
                    userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                    userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001002"));
                    autoTenderLogList.add(userAutoTenderLog);
                    continue;
                }
            }
            // 自动投标年率校验
            if (borrowAuto.getAprDown() != 0 && borrowAuto.getAprDown() > borrow.getApr()) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001003"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }
            // 自动投标借款期限校验
            if (borrowAuto.getTimelimitUp() != 0) {
                // 判断当前标为天标的情况
                if (borrow.getBorrowTimeType() == 1) {
                    if (borrowAuto.getTimelimitDown() >= 1) {
                        userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                        userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001004"));
                        autoTenderLogList.add(userAutoTenderLog);
                        continue;
                    }
                } else { // 当前标是月标
                    if (borrowAuto.getTimelimitUp() < borrow.getTimeLimit()
                            || borrowAuto.getTimelimitDown() > borrow.getTimeLimit()) {
                        userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                        userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001004"));
                        autoTenderLogList.add(userAutoTenderLog);
                        continue;
                    }
                }
            }
            // 最终投资金额
            double money = 0;
            // 设置的自动投标金额
            double autoMoney = borrowAuto.getMoney();
            Account account = accountDao.findByUserId(user.getUserId());
            double useMoney = account.getUseMoney();
            // 标最小投标金额
            double lowestAccount = borrow.getLowestAccount();
            //如果可用 不足 标最小限额，那么直接跳出循环
            if (lowestAccount > useMoney) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001005"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }
            // 标最大投标金额
            double mostAccount = borrow.getMostAccount();

            //自动投标方式 对应的 金额算法
            if (borrowAuto.getTenderStyle() == BorrowAutoType.BALANCE_FULL) { // 投资方式：余额全投
                money = useMoney;
            } else if (borrowAuto.getTenderStyle() == BorrowAutoType.FIXED_ACCOUNT) { // 投资方式：固定金额
                if (autoMoney < lowestAccount || (autoMoney > mostAccount && mostAccount > 0)) {
                    userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                    userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001013"));
                    autoTenderLogList.add(userAutoTenderLog);
                    continue;
                } else if (autoMoney > useMoney) {
                    userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                    userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001006"));
                    autoTenderLogList.add(userAutoTenderLog);
                    continue;
                } else {
                    money = autoMoney;
                }
            } else if (borrowAuto.getTenderStyle() == BorrowAutoType.ACCOUNT_INTERVAL) { // 投资方式：金额区间
                if (borrowAuto.getMax() < lowestAccount || (borrowAuto.getMin() > mostAccount && mostAccount > 0)) {
                    userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                    userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001013"));
                    autoTenderLogList.add(userAutoTenderLog);
                    continue;
                } else if (borrowAuto.getMin() > useMoney) {
                    userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                    userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001006"));
                    autoTenderLogList.add(userAutoTenderLog);
                    continue;
                } else if (useMoney > borrowAuto.getMin() && useMoney < borrowAuto.getMax()) {
                    money = useMoney;
                } else if (useMoney > borrowAuto.getMax()) {
                    money = borrowAuto.getMax();
                }
            } else { // 投资方式设置异常
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001007"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }

            //如果投标金额 不足 标最小限额，那么直接跳出循环
            if (money < lowestAccount) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001008"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }

            //如果投标金额 大于 标最大限额，那么投资金额取最大限额
            if (mostAccount > 0 && money > mostAccount) {
                money = mostAccount;
            }

            if (money > lastAccount) {
                money = lastAccount;
            }

            //如果 投资金额 大于最大自动投标金额，那么取最大投标金额
            if (money > autoTenderMaxAcount) {
                money = autoTenderMaxAcount;
            }

            money = (int) money;
            // 可用余额必须大于等于最终投资金额
            if (useMoney < money || money == 0) {
                userAutoTenderLog.setStatus(UserAutoTenderLogModel.TENDER_FAIL);
                userAutoTenderLog.setRemark(MessageUtil.getMessage("MF105001009"));
                autoTenderLogList.add(userAutoTenderLog);
                continue;
            }

            totalAccountYes = BigDecimalUtil.add(totalAccountYes, money);

            //循环结束或者自动投标金额
            if (autoList.size() == num) {
                resultFlag = "lastFlag";
            }
            //自动投标加入队列
            ConcurrentUtil.tppAutoTender(money, autoTenderMaxAcount, borrow, user, resultFlag);
            // 更新auto时间
            borrowAuto.setUpdateTime(DateUtil.getNow());
            borrowAutoDao.update(borrowAuto);
        }
        //保存自动投标记录
        if (autoTenderLogList.size() > 0) {
            userAutoTenderLogDao.save(autoTenderLogList);
        }

        //如果没有最后一条的标记，代表没有自动投标或者自动投标已出现异常，需要强制更新标状态
        if (resultFlag == "") {
            borrowDao.updateStatus(borrow.getId(), 1, 19);
        }
        logger.info("自动投标业务逻辑完成.....");
    }

    /* (non-Javadoc)
     * @see com.qdlc.p2p.biz.service.AutoBorrowService#autoVerifyFull(com.qdlc.p2p.dal.dto.Borrow)
     */
    @Override
    public void autoVerifyFull(Borrow borrow) throws Exception {
        if (null == borrow) {
            throw new BorrowException("满标复审传入参数为null！", BorrowException.TYPE_JSON);
        }

        Borrow borrowTmp = borrowDao.find(borrow.getId());
        if (null == borrowTmp) {
            throw new BorrowException("该借款标已不存在该系统中,borrowId: " + borrow.getId(), BorrowException.TYPE_JSON);
        }

        BorrowModel borrowModel = BorrowModel.instance(borrowTmp);
        BorrowWorker worker = BorrowHelper.getWorker(borrowModel);

        // 标的状态改为3，满标复审中
        worker.skipReview();
    }

    @Override
    public void autoCancel(Borrow borrow) {
        borrowFullVerifyService.cancelBorrow(BorrowModel.instance(borrow));
    }

    /**
     * 代偿成功后处理
     *
     * @param borrowRepayment
     */
    @Override
    public void autoCompensateSuccess(BorrowRepayment borrowRepayment) {
        Borrow borrow = borrowDao.find(borrowRepayment.getBorrow().getId());
        BorrowWorker worker = BorrowHelper.getWorker(borrow);
        try {
            // 担保公司
            User user = borrow.getVouchFirm();
            // 处理投资人资金
            worker.borrowRepayHandleTender(borrowRepayment);
            borrowRepayment.setStatus(BorrowRepaymentStatus.STATUS_YES_REPAY);// 已还款
            borrowRepayment.setRepaymentYesTime(DateUtil.getNow());
            borrowRepayment.setRepaymentYesAccount(BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest(), borrowRepayment.getLateInterest()));
            // 还款类型1：代偿
            borrowRepayment.setType(BorrowRepaymentType.REPAYMENT_TYPE_COMPENSATE);
            // 实际还款者
            borrowRepayment.setRealRepayer(user);
            borrowRepaymentDao.updateBorrowRepaymentByStatus(borrowRepayment);
            int status = worker.isLastPeriod(borrowRepayment.getPeriod()) ? 8 : 7;
            borrow.setStatus(status);
            double total = BigDecimalUtil.add(borrowRepayment.getCapital(), borrowRepayment.getInterest()); // 还款表本金+利息
            borrow.setRepaymentYesAccount(BigDecimalUtil.add(borrow.getRepaymentYesAccount(), total));
            borrow.setRepaymentYesInterest(BigDecimalUtil.add(borrow.getRepaymentYesInterest(), borrowRepayment.getInterest()));
            borrowDao.update(borrow);
            // 向担保公司发送担保还款成功通知
            Global.setTransfer("borrow", borrow);
            Global.setTransfer("repay", borrowRepayment);
            Global.setTransfer("user", user);
            AbstractExecuter successExecuter = ExecuterHelper.getExecuter(BorrowCompensateSuccessExecuter.class);
            successExecuter.execute(0, user);
        } catch (Exception e) {
            logger.error("代偿失败" + e.getMessage());
            throw new BorrowException("代偿失败" + e.getMessage());
        }

    }

    @Override
    public void updateStatus(long id, int status, int preStatus) {
        borrowDao.updateStatus(id, status, preStatus);
    }

    /**
     * 由于托管分批次还款数据
     *
     * @param repay
     */
    public BorrowRepayment getResealRepay(BorrowRepayment repay) {
        repay.setRepaymentYesAccount(BigDecimalUtil.add(repay.getCapital(), repay.getInterest()));
        return repay;
    }

    /**
     * 环迅还款后回调：如果此次还款的代收里面，有任何一个待收不是待还款状态，则返回false 如果成功，则计算本次应还的金额
     *
     * @param repay 还款
     * @return 成功/失败
     */
    private BorrowRepayment checkRepay(BorrowRepayment repay) {
        if (repay.getStatus() != BorrowRepaymentStatus.STATUS_WAIT_REPAY && repay.getStatus() != BorrowRepaymentStatus.STATUS_REPAY_ING) {
            throw new BorrowException("请勿重复还款");
        }
        return repay;
    }
}
